@code-pushup/cli 0.44.4 → 0.45.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/index.js +390 -387
  2. package/package.json +4 -4
package/index.js CHANGED
@@ -115,6 +115,7 @@ var fileNameSchema = z.string().trim().regex(filenameRegex, {
115
115
  }).min(1, { message: "file name is invalid" });
116
116
  var positiveIntSchema = z.number().int().positive();
117
117
  var nonnegativeIntSchema = z.number().int().nonnegative();
118
+ var nonnegativeNumberSchema = z.number().nonnegative();
118
119
  function packageVersionSchema(options2) {
119
120
  const { versionDescription = "NPM version of the package", required } = options2 ?? {};
120
121
  const packageSchema = z.string({ description: "NPM package name" });
@@ -127,7 +128,7 @@ function packageVersionSchema(options2) {
127
128
  { description: "NPM package name and version of a published package" }
128
129
  );
129
130
  }
130
- var weightSchema = nonnegativeIntSchema.describe(
131
+ var weightSchema = nonnegativeNumberSchema.describe(
131
132
  "Coefficient for the given score (use weight 0 if only for display)"
132
133
  );
133
134
  function weightedRefSchema(description, slugDescription) {
@@ -269,7 +270,7 @@ var tableObjectSchema = tableSharedSchema.merge(
269
270
  var tableSchema = (description = "Table information") => z4.union([tablePrimitiveSchema, tableObjectSchema], { description });
270
271
 
271
272
  // packages/models/src/lib/audit-output.ts
272
- var auditValueSchema = nonnegativeIntSchema.describe("Raw numeric value");
273
+ var auditValueSchema = nonnegativeNumberSchema.describe("Raw numeric value");
273
274
  var auditDisplayValueSchema = z5.string({ description: "Formatted value (e.g. '0.9 s', '2.1 MB')" }).optional();
274
275
  var auditDetailsSchema = z5.object(
275
276
  {
@@ -709,399 +710,114 @@ var reportsDiffSchema = z15.object({
709
710
  })
710
711
  );
711
712
 
712
- // packages/utils/src/lib/text-formats/constants.ts
713
- var NEW_LINE = "\n";
714
- var TAB = " ";
715
- var SPACE = " ";
716
-
717
- // packages/utils/src/lib/text-formats/html/details.ts
718
- function details(title, content, cfg = { open: false }) {
719
- return `<details${cfg.open ? " open" : ""}>${NEW_LINE}<summary>${title}</summary>${NEW_LINE}${// ⚠️ The blank line is needed to ensure Markdown in content is rendered correctly.
720
- NEW_LINE}${content}${NEW_LINE}${// @TODO in the future we could consider adding it only if the content ends with a code block
721
- // ⚠️ The blank line ensure Markdown in content is rendered correctly.
722
- NEW_LINE}</details>${// ⚠️ The blank line is needed to ensure Markdown after details is rendered correctly.
723
- NEW_LINE}`;
724
- }
725
-
726
- // packages/utils/src/lib/text-formats/html/font-style.ts
727
- var boldElement = "b";
728
- function bold(text) {
729
- return `<${boldElement}>${text}</${boldElement}>`;
730
- }
731
- var italicElement = "i";
732
- function italic(text) {
733
- return `<${italicElement}>${text}</${italicElement}>`;
713
+ // packages/utils/src/lib/diff.ts
714
+ function matchArrayItemsByKey({
715
+ before,
716
+ after,
717
+ key
718
+ }) {
719
+ const pairs = [];
720
+ const added = [];
721
+ const afterKeys = /* @__PURE__ */ new Set();
722
+ const keyFn = typeof key === "function" ? key : (item) => item[key];
723
+ for (const afterItem of after) {
724
+ const afterKey = keyFn(afterItem);
725
+ afterKeys.add(afterKey);
726
+ const match = before.find((beforeItem) => keyFn(beforeItem) === afterKey);
727
+ if (match) {
728
+ pairs.push({ before: match, after: afterItem });
729
+ } else {
730
+ added.push(afterItem);
731
+ }
732
+ }
733
+ const removed = before.filter(
734
+ (beforeItem) => !afterKeys.has(keyFn(beforeItem))
735
+ );
736
+ return {
737
+ pairs,
738
+ added,
739
+ removed
740
+ };
734
741
  }
735
- var codeElement = "code";
736
- function code(text) {
737
- return `<${codeElement}>${text}</${codeElement}>`;
742
+ function comparePairs(pairs, equalsFn) {
743
+ return pairs.reduce(
744
+ (acc, pair) => ({
745
+ ...acc,
746
+ ...equalsFn(pair) ? { unchanged: [...acc.unchanged, pair.after] } : { changed: [...acc.changed, pair] }
747
+ }),
748
+ {
749
+ changed: [],
750
+ unchanged: []
751
+ }
752
+ );
738
753
  }
739
754
 
740
- // packages/utils/src/lib/text-formats/html/link.ts
741
- function link(href, text) {
742
- return `<a href="${href}">${text || href}"</a>`;
743
- }
755
+ // packages/utils/src/lib/execute-process.ts
756
+ import { spawn } from "node:child_process";
744
757
 
745
- // packages/utils/src/lib/transform.ts
746
- function toArray(val) {
747
- return Array.isArray(val) ? val : [val];
748
- }
749
- function objectToEntries(obj) {
750
- return Object.entries(obj);
751
- }
752
- function deepClone(obj) {
753
- return obj == null || typeof obj !== "object" ? obj : structuredClone(obj);
754
- }
755
- function toUnixPath(path) {
756
- return path.replace(/\\/g, "/");
757
- }
758
- function capitalize(text) {
759
- return `${text.charAt(0).toLocaleUpperCase()}${text.slice(
760
- 1
761
- )}`;
762
- }
758
+ // packages/utils/src/lib/reports/utils.ts
759
+ import { join } from "node:path";
763
760
 
764
- // packages/utils/src/lib/table.ts
765
- function rowToStringArray({ rows, columns = [] }) {
766
- if (Array.isArray(rows.at(0)) && typeof columns.at(0) === "object") {
767
- throw new TypeError(
768
- "Column can`t be object when rows are primitive values"
769
- );
770
- }
771
- return rows.map((row) => {
772
- if (Array.isArray(row)) {
773
- return row.map(String);
774
- }
775
- const objectRow = row;
776
- if (columns.length === 0 || typeof columns.at(0) === "string") {
777
- return Object.values(objectRow).map(String);
778
- }
779
- return columns.map(
780
- ({ key }) => String(objectRow[key])
781
- );
782
- });
761
+ // packages/utils/src/lib/file-system.ts
762
+ import { bundleRequire } from "bundle-require";
763
+ import chalk2 from "chalk";
764
+ import { mkdir, readFile, readdir, rm, stat } from "node:fs/promises";
765
+
766
+ // packages/utils/src/lib/formatting.ts
767
+ function slugify(text) {
768
+ return text.trim().toLowerCase().replace(/\s+|\//g, "-").replace(/[^a-z\d-]/g, "");
783
769
  }
784
- function columnsToStringArray({ rows, columns = [] }) {
785
- const firstRow = rows.at(0);
786
- const primitiveRows = Array.isArray(firstRow);
787
- if (typeof columns.at(0) === "string" && !primitiveRows) {
788
- throw new Error("invalid union type. Caught by model parsing.");
770
+ function pluralize(text, amount) {
771
+ if (amount != null && Math.abs(amount) === 1) {
772
+ return text;
789
773
  }
790
- if (columns.length === 0) {
791
- if (Array.isArray(firstRow)) {
792
- return firstRow.map((_, idx) => String(idx));
793
- }
794
- return Object.keys(firstRow);
774
+ if (text.endsWith("y")) {
775
+ return `${text.slice(0, -1)}ies`;
795
776
  }
796
- if (typeof columns.at(0) === "string") {
797
- return columns.map(String);
777
+ if (text.endsWith("s")) {
778
+ return `${text}es`;
798
779
  }
799
- const cols = columns;
800
- return cols.map(({ label, key }) => label ?? capitalize(key));
780
+ return `${text}s`;
801
781
  }
802
- function getColumnAlignmentForKeyAndIndex(targetKey, targetIdx, columns = []) {
803
- const column = columns.at(targetIdx) ?? columns.find((col) => col.key === targetKey);
804
- if (typeof column === "string") {
805
- return column;
806
- } else if (typeof column === "object") {
807
- return column.align ?? "center";
808
- } else {
809
- return "center";
782
+ function formatBytes(bytes, decimals = 2) {
783
+ const positiveBytes = Math.max(bytes, 0);
784
+ if (positiveBytes === 0) {
785
+ return "0 B";
810
786
  }
787
+ const k = 1024;
788
+ const dm = decimals < 0 ? 0 : decimals;
789
+ const sizes = ["B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
790
+ const i = Math.floor(Math.log(positiveBytes) / Math.log(k));
791
+ return `${Number.parseFloat((positiveBytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
811
792
  }
812
- function getColumnAlignmentForIndex(targetIdx, columns = []) {
813
- const column = columns.at(targetIdx);
814
- if (column == null) {
815
- return "center";
816
- } else if (typeof column === "string") {
817
- return column;
818
- } else if (typeof column === "object") {
819
- return column.align ?? "center";
820
- } else {
821
- return "center";
822
- }
793
+ function pluralizeToken(token, times) {
794
+ return `${times} ${Math.abs(times) === 1 ? token : pluralize(token)}`;
823
795
  }
824
- function getColumnAlignments({
825
- rows,
826
- columns = []
827
- }) {
828
- if (rows.at(0) == null) {
829
- throw new Error("first row can`t be undefined.");
830
- }
831
- if (Array.isArray(rows.at(0))) {
832
- const firstPrimitiveRow = rows.at(0);
833
- return Array.from({ length: firstPrimitiveRow.length }).map(
834
- (_, idx) => getColumnAlignmentForIndex(idx, columns)
835
- );
796
+ function formatDuration(duration) {
797
+ if (duration < 1e3) {
798
+ return `${duration} ms`;
836
799
  }
837
- const firstObject = rows.at(0);
838
- return Object.keys(firstObject).map(
839
- (key, idx) => getColumnAlignmentForKeyAndIndex(key, idx, columns)
840
- );
841
- }
842
-
843
- // packages/utils/src/lib/text-formats/html/table.ts
844
- function wrap(elem, content) {
845
- return `<${elem}>${content}</${elem}>${NEW_LINE}`;
846
- }
847
- function wrapRow(content) {
848
- const elem = "tr";
849
- return `<${elem}>${NEW_LINE}${content}</${elem}>${NEW_LINE}`;
800
+ return `${(duration / 1e3).toFixed(2)} s`;
850
801
  }
851
- function table(tableData) {
852
- if (tableData.rows.length === 0) {
853
- throw new Error("Data can't be empty");
854
- }
855
- const tableHeaderCols = columnsToStringArray(tableData).map((s) => wrap("th", s)).join("");
856
- const tableHeaderRow = wrapRow(tableHeaderCols);
857
- const tableBody = rowToStringArray(tableData).map((arr) => {
858
- const columns = arr.map((s) => wrap("td", s)).join("");
859
- return wrapRow(columns);
860
- }).join("");
861
- return wrap("table", `${NEW_LINE}${tableHeaderRow}${tableBody}`);
802
+ function formatDate(date) {
803
+ const locale = "en-US";
804
+ return date.toLocaleString(locale, {
805
+ weekday: "short",
806
+ month: "short",
807
+ day: "numeric",
808
+ year: "numeric",
809
+ hour: "numeric",
810
+ minute: "2-digit",
811
+ timeZoneName: "short"
812
+ }).replace(/\u202F/g, " ");
862
813
  }
863
814
 
864
- // packages/utils/src/lib/text-formats/md/font-style.ts
865
- var boldWrap = "**";
866
- function bold2(text) {
867
- return `${boldWrap}${text}${boldWrap}`;
868
- }
869
- var italicWrap = "_";
870
- function italic2(text) {
871
- return `${italicWrap}${text}${italicWrap}`;
872
- }
873
- var strikeThroughWrap = "~";
874
- function strikeThrough(text) {
875
- return `${strikeThroughWrap}${text}${strikeThroughWrap}`;
815
+ // packages/utils/src/lib/guards.ts
816
+ function isPromiseFulfilledResult(result) {
817
+ return result.status === "fulfilled";
876
818
  }
877
- var codeWrap = "`";
878
- function code2(text) {
879
- return `${codeWrap}${text}${codeWrap}`;
880
- }
881
-
882
- // packages/utils/src/lib/text-formats/md/headline.ts
883
- function headline(text, hierarchy = 1) {
884
- return `${"#".repeat(hierarchy)} ${text}${NEW_LINE}`;
885
- }
886
- function h(text, hierarchy = 1) {
887
- return headline(text, hierarchy);
888
- }
889
- function h1(text) {
890
- return headline(text, 1);
891
- }
892
- function h2(text) {
893
- return headline(text, 2);
894
- }
895
- function h3(text) {
896
- return headline(text, 3);
897
- }
898
- function h4(text) {
899
- return headline(text, 4);
900
- }
901
- function h5(text) {
902
- return headline(text, 5);
903
- }
904
- function h6(text) {
905
- return headline(text, 6);
906
- }
907
-
908
- // packages/utils/src/lib/text-formats/md/image.ts
909
- function image(src, alt) {
910
- return `![${alt}](${src})`;
911
- }
912
-
913
- // packages/utils/src/lib/text-formats/md/link.ts
914
- function link2(href, text) {
915
- return `[${text || href}](${href})`;
916
- }
917
-
918
- // packages/utils/src/lib/text-formats/md/list.ts
919
- function li(text, order = "unordered") {
920
- const style = order === "unordered" ? "-" : "- [ ]";
921
- return `${style} ${text}`;
922
- }
923
- function indentation(text, level = 1) {
924
- return `${TAB.repeat(level)}${text}`;
925
- }
926
-
927
- // packages/utils/src/lib/text-formats/md/paragraphs.ts
928
- function paragraphs(...sections) {
929
- return sections.filter(Boolean).join(`${NEW_LINE}${NEW_LINE}`);
930
- }
931
-
932
- // packages/utils/src/lib/text-formats/md/section.ts
933
- function section(...contents) {
934
- return `${lines(...contents)}${NEW_LINE}`;
935
- }
936
- function lines(...contents) {
937
- return `${contents.filter(Boolean).join(NEW_LINE)}`;
938
- }
939
-
940
- // packages/utils/src/lib/text-formats/md/table.ts
941
- var alignString = /* @__PURE__ */ new Map([
942
- ["left", ":--"],
943
- ["center", ":--:"],
944
- ["right", "--:"]
945
- ]);
946
- function tableRow(rows) {
947
- return `|${rows.join("|")}|`;
948
- }
949
- function table2(data) {
950
- if (data.rows.length === 0) {
951
- throw new Error("Data can't be empty");
952
- }
953
- const alignmentRow = getColumnAlignments(data).map(
954
- (s) => alignString.get(s) ?? String(alignString.get("center"))
955
- );
956
- return section(
957
- `${lines(
958
- tableRow(columnsToStringArray(data)),
959
- tableRow(alignmentRow),
960
- ...rowToStringArray(data).map(tableRow)
961
- )}`
962
- );
963
- }
964
-
965
- // packages/utils/src/lib/text-formats/index.ts
966
- var md = {
967
- bold: bold2,
968
- italic: italic2,
969
- strikeThrough,
970
- code: code2,
971
- link: link2,
972
- image,
973
- headline,
974
- h,
975
- h1,
976
- h2,
977
- h3,
978
- h4,
979
- h5,
980
- h6,
981
- indentation,
982
- lines,
983
- li,
984
- section,
985
- paragraphs,
986
- table: table2
987
- };
988
- var html = {
989
- bold,
990
- italic,
991
- code,
992
- link,
993
- details,
994
- table
995
- };
996
-
997
- // packages/utils/src/lib/diff.ts
998
- function matchArrayItemsByKey({
999
- before,
1000
- after,
1001
- key
1002
- }) {
1003
- const pairs = [];
1004
- const added = [];
1005
- const afterKeys = /* @__PURE__ */ new Set();
1006
- const keyFn = typeof key === "function" ? key : (item) => item[key];
1007
- for (const afterItem of after) {
1008
- const afterKey = keyFn(afterItem);
1009
- afterKeys.add(afterKey);
1010
- const match = before.find((beforeItem) => keyFn(beforeItem) === afterKey);
1011
- if (match) {
1012
- pairs.push({ before: match, after: afterItem });
1013
- } else {
1014
- added.push(afterItem);
1015
- }
1016
- }
1017
- const removed = before.filter(
1018
- (beforeItem) => !afterKeys.has(keyFn(beforeItem))
1019
- );
1020
- return {
1021
- pairs,
1022
- added,
1023
- removed
1024
- };
1025
- }
1026
- function comparePairs(pairs, equalsFn) {
1027
- return pairs.reduce(
1028
- (acc, pair) => ({
1029
- ...acc,
1030
- ...equalsFn(pair) ? { unchanged: [...acc.unchanged, pair.after] } : { changed: [...acc.changed, pair] }
1031
- }),
1032
- {
1033
- changed: [],
1034
- unchanged: []
1035
- }
1036
- );
1037
- }
1038
-
1039
- // packages/utils/src/lib/execute-process.ts
1040
- import { spawn } from "node:child_process";
1041
-
1042
- // packages/utils/src/lib/reports/utils.ts
1043
- import { join } from "node:path";
1044
-
1045
- // packages/utils/src/lib/file-system.ts
1046
- import { bundleRequire } from "bundle-require";
1047
- import chalk2 from "chalk";
1048
- import { mkdir, readFile, readdir, rm, stat } from "node:fs/promises";
1049
-
1050
- // packages/utils/src/lib/formatting.ts
1051
- function slugify(text) {
1052
- return text.trim().toLowerCase().replace(/\s+|\//g, "-").replace(/[^a-z\d-]/g, "");
1053
- }
1054
- function pluralize(text, amount) {
1055
- if (amount != null && Math.abs(amount) === 1) {
1056
- return text;
1057
- }
1058
- if (text.endsWith("y")) {
1059
- return `${text.slice(0, -1)}ies`;
1060
- }
1061
- if (text.endsWith("s")) {
1062
- return `${text}es`;
1063
- }
1064
- return `${text}s`;
1065
- }
1066
- function formatBytes(bytes, decimals = 2) {
1067
- const positiveBytes = Math.max(bytes, 0);
1068
- if (positiveBytes === 0) {
1069
- return "0 B";
1070
- }
1071
- const k = 1024;
1072
- const dm = decimals < 0 ? 0 : decimals;
1073
- const sizes = ["B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
1074
- const i = Math.floor(Math.log(positiveBytes) / Math.log(k));
1075
- return `${Number.parseFloat((positiveBytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
1076
- }
1077
- function pluralizeToken(token, times) {
1078
- return `${times} ${Math.abs(times) === 1 ? token : pluralize(token)}`;
1079
- }
1080
- function formatDuration(duration) {
1081
- if (duration < 1e3) {
1082
- return `${duration} ms`;
1083
- }
1084
- return `${(duration / 1e3).toFixed(2)} s`;
1085
- }
1086
- function formatDate(date) {
1087
- const locale = "en-US";
1088
- return date.toLocaleString(locale, {
1089
- weekday: "short",
1090
- month: "short",
1091
- day: "numeric",
1092
- year: "numeric",
1093
- hour: "numeric",
1094
- minute: "2-digit",
1095
- timeZoneName: "short"
1096
- }).replace(/\u202F/g, " ");
1097
- }
1098
-
1099
- // packages/utils/src/lib/guards.ts
1100
- function isPromiseFulfilledResult(result) {
1101
- return result.status === "fulfilled";
1102
- }
1103
- function isPromiseRejectedResult(result) {
1104
- return result.status === "rejected";
819
+ function isPromiseRejectedResult(result) {
820
+ return result.status === "rejected";
1105
821
  }
1106
822
 
1107
823
  // packages/utils/src/lib/logging.ts
@@ -1178,7 +894,7 @@ function logListItem(args) {
1178
894
  singletonisaacUi.rows = [];
1179
895
  singletonUiInstance?.logger.log(content);
1180
896
  }
1181
- function link3(text) {
897
+ function link(text) {
1182
898
  return chalk.underline(chalk.blueBright(text));
1183
899
  }
1184
900
 
@@ -1281,10 +997,297 @@ async function importEsmModule(options2) {
1281
997
  return mod.default;
1282
998
  }
1283
999
 
1000
+ // packages/utils/src/lib/text-formats/constants.ts
1001
+ var NEW_LINE = "\n";
1002
+ var TAB = " ";
1003
+ var SPACE = " ";
1004
+
1005
+ // packages/utils/src/lib/text-formats/html/details.ts
1006
+ function details(title, content, cfg = { open: false }) {
1007
+ return `<details${cfg.open ? " open" : ""}>${NEW_LINE}<summary>${title}</summary>${NEW_LINE}${// ⚠️ The blank line is needed to ensure Markdown in content is rendered correctly.
1008
+ NEW_LINE}${content}${NEW_LINE}${// @TODO in the future we could consider adding it only if the content ends with a code block
1009
+ // ⚠️ The blank line ensure Markdown in content is rendered correctly.
1010
+ NEW_LINE}</details>${// ⚠️ The blank line is needed to ensure Markdown after details is rendered correctly.
1011
+ NEW_LINE}`;
1012
+ }
1013
+
1014
+ // packages/utils/src/lib/text-formats/html/font-style.ts
1015
+ var boldElement = "b";
1016
+ function bold(text) {
1017
+ return `<${boldElement}>${text}</${boldElement}>`;
1018
+ }
1019
+ var italicElement = "i";
1020
+ function italic(text) {
1021
+ return `<${italicElement}>${text}</${italicElement}>`;
1022
+ }
1023
+ var codeElement = "code";
1024
+ function code(text) {
1025
+ return `<${codeElement}>${text}</${codeElement}>`;
1026
+ }
1027
+
1028
+ // packages/utils/src/lib/text-formats/html/link.ts
1029
+ function link2(href, text) {
1030
+ return `<a href="${href}">${text || href}"</a>`;
1031
+ }
1032
+
1033
+ // packages/utils/src/lib/transform.ts
1034
+ function toArray(val) {
1035
+ return Array.isArray(val) ? val : [val];
1036
+ }
1037
+ function objectToEntries(obj) {
1038
+ return Object.entries(obj);
1039
+ }
1040
+ function deepClone(obj) {
1041
+ return obj == null || typeof obj !== "object" ? obj : structuredClone(obj);
1042
+ }
1043
+ function toUnixPath(path) {
1044
+ return path.replace(/\\/g, "/");
1045
+ }
1046
+ function capitalize(text) {
1047
+ return `${text.charAt(0).toLocaleUpperCase()}${text.slice(
1048
+ 1
1049
+ )}`;
1050
+ }
1051
+
1052
+ // packages/utils/src/lib/table.ts
1053
+ function rowToStringArray({ rows, columns = [] }) {
1054
+ if (Array.isArray(rows.at(0)) && typeof columns.at(0) === "object") {
1055
+ throw new TypeError(
1056
+ "Column can`t be object when rows are primitive values"
1057
+ );
1058
+ }
1059
+ return rows.map((row) => {
1060
+ if (Array.isArray(row)) {
1061
+ return row.map(String);
1062
+ }
1063
+ const objectRow = row;
1064
+ if (columns.length === 0 || typeof columns.at(0) === "string") {
1065
+ return Object.values(objectRow).map(String);
1066
+ }
1067
+ return columns.map(
1068
+ ({ key }) => String(objectRow[key])
1069
+ );
1070
+ });
1071
+ }
1072
+ function columnsToStringArray({ rows, columns = [] }) {
1073
+ const firstRow = rows.at(0);
1074
+ const primitiveRows = Array.isArray(firstRow);
1075
+ if (typeof columns.at(0) === "string" && !primitiveRows) {
1076
+ throw new Error("invalid union type. Caught by model parsing.");
1077
+ }
1078
+ if (columns.length === 0) {
1079
+ if (Array.isArray(firstRow)) {
1080
+ return firstRow.map((_, idx) => String(idx));
1081
+ }
1082
+ return Object.keys(firstRow);
1083
+ }
1084
+ if (typeof columns.at(0) === "string") {
1085
+ return columns.map(String);
1086
+ }
1087
+ const cols = columns;
1088
+ return cols.map(({ label, key }) => label ?? capitalize(key));
1089
+ }
1090
+ function getColumnAlignmentForKeyAndIndex(targetKey, targetIdx, columns = []) {
1091
+ const column = columns.at(targetIdx) ?? columns.find((col) => col.key === targetKey);
1092
+ if (typeof column === "string") {
1093
+ return column;
1094
+ } else if (typeof column === "object") {
1095
+ return column.align ?? "center";
1096
+ } else {
1097
+ return "center";
1098
+ }
1099
+ }
1100
+ function getColumnAlignmentForIndex(targetIdx, columns = []) {
1101
+ const column = columns.at(targetIdx);
1102
+ if (column == null) {
1103
+ return "center";
1104
+ } else if (typeof column === "string") {
1105
+ return column;
1106
+ } else if (typeof column === "object") {
1107
+ return column.align ?? "center";
1108
+ } else {
1109
+ return "center";
1110
+ }
1111
+ }
1112
+ function getColumnAlignments({
1113
+ rows,
1114
+ columns = []
1115
+ }) {
1116
+ if (rows.at(0) == null) {
1117
+ throw new Error("first row can`t be undefined.");
1118
+ }
1119
+ if (Array.isArray(rows.at(0))) {
1120
+ const firstPrimitiveRow = rows.at(0);
1121
+ return Array.from({ length: firstPrimitiveRow.length }).map(
1122
+ (_, idx) => getColumnAlignmentForIndex(idx, columns)
1123
+ );
1124
+ }
1125
+ const firstObject = rows.at(0);
1126
+ return Object.keys(firstObject).map(
1127
+ (key, idx) => getColumnAlignmentForKeyAndIndex(key, idx, columns)
1128
+ );
1129
+ }
1130
+
1131
+ // packages/utils/src/lib/text-formats/html/table.ts
1132
+ function wrap(elem, content) {
1133
+ return `<${elem}>${content}</${elem}>${NEW_LINE}`;
1134
+ }
1135
+ function wrapRow(content) {
1136
+ const elem = "tr";
1137
+ return `<${elem}>${NEW_LINE}${content}</${elem}>${NEW_LINE}`;
1138
+ }
1139
+ function table(tableData) {
1140
+ if (tableData.rows.length === 0) {
1141
+ throw new Error("Data can't be empty");
1142
+ }
1143
+ const tableHeaderCols = columnsToStringArray(tableData).map((s) => wrap("th", s)).join("");
1144
+ const tableHeaderRow = wrapRow(tableHeaderCols);
1145
+ const tableBody = rowToStringArray(tableData).map((arr) => {
1146
+ const columns = arr.map((s) => wrap("td", s)).join("");
1147
+ return wrapRow(columns);
1148
+ }).join("");
1149
+ return wrap("table", `${NEW_LINE}${tableHeaderRow}${tableBody}`);
1150
+ }
1151
+
1152
+ // packages/utils/src/lib/text-formats/md/font-style.ts
1153
+ var boldWrap = "**";
1154
+ function bold2(text) {
1155
+ return `${boldWrap}${text}${boldWrap}`;
1156
+ }
1157
+ var italicWrap = "_";
1158
+ function italic2(text) {
1159
+ return `${italicWrap}${text}${italicWrap}`;
1160
+ }
1161
+ var strikeThroughWrap = "~";
1162
+ function strikeThrough(text) {
1163
+ return `${strikeThroughWrap}${text}${strikeThroughWrap}`;
1164
+ }
1165
+ var codeWrap = "`";
1166
+ function code2(text) {
1167
+ return `${codeWrap}${text}${codeWrap}`;
1168
+ }
1169
+
1170
+ // packages/utils/src/lib/text-formats/md/headline.ts
1171
+ function headline(text, hierarchy = 1) {
1172
+ return `${"#".repeat(hierarchy)} ${text}${NEW_LINE}`;
1173
+ }
1174
+ function h(text, hierarchy = 1) {
1175
+ return headline(text, hierarchy);
1176
+ }
1177
+ function h1(text) {
1178
+ return headline(text, 1);
1179
+ }
1180
+ function h2(text) {
1181
+ return headline(text, 2);
1182
+ }
1183
+ function h3(text) {
1184
+ return headline(text, 3);
1185
+ }
1186
+ function h4(text) {
1187
+ return headline(text, 4);
1188
+ }
1189
+ function h5(text) {
1190
+ return headline(text, 5);
1191
+ }
1192
+ function h6(text) {
1193
+ return headline(text, 6);
1194
+ }
1195
+
1196
+ // packages/utils/src/lib/text-formats/md/image.ts
1197
+ function image(src, alt) {
1198
+ return `![${alt}](${src})`;
1199
+ }
1200
+
1201
+ // packages/utils/src/lib/text-formats/md/link.ts
1202
+ function link3(href, text) {
1203
+ return `[${text || href}](${href})`;
1204
+ }
1205
+
1206
+ // packages/utils/src/lib/text-formats/md/list.ts
1207
+ function li(text, order = "unordered") {
1208
+ const style = order === "unordered" ? "-" : "- [ ]";
1209
+ return `${style} ${text}`;
1210
+ }
1211
+ function indentation(text, level = 1) {
1212
+ return `${TAB.repeat(level)}${text}`;
1213
+ }
1214
+
1215
+ // packages/utils/src/lib/text-formats/md/paragraphs.ts
1216
+ function paragraphs(...sections) {
1217
+ return sections.filter(Boolean).join(`${NEW_LINE}${NEW_LINE}`);
1218
+ }
1219
+
1220
+ // packages/utils/src/lib/text-formats/md/section.ts
1221
+ function section(...contents) {
1222
+ return `${lines(...contents)}${NEW_LINE}`;
1223
+ }
1224
+ function lines(...contents) {
1225
+ return `${contents.filter(Boolean).join(NEW_LINE)}`;
1226
+ }
1227
+
1228
+ // packages/utils/src/lib/text-formats/md/table.ts
1229
+ var alignString = /* @__PURE__ */ new Map([
1230
+ ["left", ":--"],
1231
+ ["center", ":--:"],
1232
+ ["right", "--:"]
1233
+ ]);
1234
+ function tableRow(rows) {
1235
+ return `|${rows.join("|")}|`;
1236
+ }
1237
+ function table2(data) {
1238
+ if (data.rows.length === 0) {
1239
+ throw new Error("Data can't be empty");
1240
+ }
1241
+ const alignmentRow = getColumnAlignments(data).map(
1242
+ (s) => alignString.get(s) ?? String(alignString.get("center"))
1243
+ );
1244
+ return section(
1245
+ `${lines(
1246
+ tableRow(columnsToStringArray(data)),
1247
+ tableRow(alignmentRow),
1248
+ ...rowToStringArray(data).map(tableRow)
1249
+ )}`
1250
+ );
1251
+ }
1252
+
1253
+ // packages/utils/src/lib/text-formats/index.ts
1254
+ var md = {
1255
+ bold: bold2,
1256
+ italic: italic2,
1257
+ strikeThrough,
1258
+ code: code2,
1259
+ link: link3,
1260
+ image,
1261
+ headline,
1262
+ h,
1263
+ h1,
1264
+ h2,
1265
+ h3,
1266
+ h4,
1267
+ h5,
1268
+ h6,
1269
+ indentation,
1270
+ lines,
1271
+ li,
1272
+ section,
1273
+ paragraphs,
1274
+ table: table2
1275
+ };
1276
+ var html = {
1277
+ bold,
1278
+ italic,
1279
+ code,
1280
+ link: link2,
1281
+ details,
1282
+ table
1283
+ };
1284
+
1284
1285
  // packages/utils/src/lib/reports/utils.ts
1285
1286
  var { image: image2, bold: boldMd } = md;
1286
1287
  function formatReportScore(score) {
1287
- return Math.round(score * 100).toString();
1288
+ const scaledScore = score * 100;
1289
+ const roundedScore = Math.round(scaledScore);
1290
+ return roundedScore === 100 && score !== 1 ? Math.floor(scaledScore).toString() : roundedScore.toString();
1288
1291
  }
1289
1292
  function formatScoreWithColor(score, options2) {
1290
1293
  const styledNumber = options2?.skipBold ? formatReportScore(score) : boldMd(formatReportScore(score));
@@ -2570,7 +2573,7 @@ var verboseUtils = (verbose = false) => ({
2570
2573
 
2571
2574
  // packages/core/package.json
2572
2575
  var name = "@code-pushup/core";
2573
- var version = "0.44.4";
2576
+ var version = "0.45.1";
2574
2577
 
2575
2578
  // packages/core/src/lib/implementation/execute-plugin.ts
2576
2579
  import chalk5 from "chalk";
@@ -3270,7 +3273,7 @@ import chalk6 from "chalk";
3270
3273
  function renderConfigureCategoriesHint() {
3271
3274
  ui().logger.info(
3272
3275
  chalk6.gray(
3273
- `\u{1F4A1} Configure categories to see the scores in an overview table. See: ${link3(
3276
+ `\u{1F4A1} Configure categories to see the scores in an overview table. See: ${link(
3274
3277
  "https://github.com/code-pushup/cli/blob/main/packages/cli/README.md"
3275
3278
  )}`
3276
3279
  )
@@ -3278,7 +3281,7 @@ function renderConfigureCategoriesHint() {
3278
3281
  }
3279
3282
  function uploadSuccessfulLog(url) {
3280
3283
  ui().logger.success("Upload successful!");
3281
- ui().logger.success(link3(url));
3284
+ ui().logger.success(link(url));
3282
3285
  }
3283
3286
  function collectSuccessfulLog() {
3284
3287
  ui().logger.success("Collecting report successful!");
@@ -3289,15 +3292,15 @@ function renderIntegratePortalHint() {
3289
3292
  "npx code-pushup upload"
3290
3293
  )}`
3291
3294
  ).add(
3292
- ` ${link3(
3295
+ ` ${link(
3293
3296
  "https://github.com/code-pushup/cli/tree/main/packages/cli#upload-command"
3294
3297
  )}`
3295
3298
  ).add(
3296
- `${chalk6.gray("\u276F")} ${chalk6.gray("Portal Integration")} - ${link3(
3299
+ `${chalk6.gray("\u276F")} ${chalk6.gray("Portal Integration")} - ${link(
3297
3300
  "https://github.com/code-pushup/cli/blob/main/packages/cli/README.md#portal-integration"
3298
3301
  )}`
3299
3302
  ).add(
3300
- `${chalk6.gray("\u276F")} ${chalk6.gray("Upload Command")} - ${link3(
3303
+ `${chalk6.gray("\u276F")} ${chalk6.gray("Upload Command")} - ${link(
3301
3304
  "https://github.com/code-pushup/cli/blob/main/packages/cli/README.md#portal-integration"
3302
3305
  )}`
3303
3306
  ).render();
@@ -3367,7 +3370,7 @@ function renderUploadAutorunHint() {
3367
3370
  "Run upload to upload the created report to the server"
3368
3371
  )}`
3369
3372
  ).add(
3370
- ` ${link3(
3373
+ ` ${link(
3371
3374
  "https://github.com/code-pushup/cli/tree/main/packages/cli#upload-command"
3372
3375
  )}`
3373
3376
  ).add(
@@ -3375,7 +3378,7 @@ function renderUploadAutorunHint() {
3375
3378
  "Run collect & upload"
3376
3379
  )}`
3377
3380
  ).add(
3378
- ` ${link3(
3381
+ ` ${link(
3379
3382
  "https://github.com/code-pushup/cli/tree/main/packages/cli#autorun-command"
3380
3383
  )}`
3381
3384
  ).render();
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "@code-pushup/cli",
3
- "version": "0.44.4",
3
+ "version": "0.45.1",
4
4
  "license": "MIT",
5
5
  "bin": {
6
6
  "code-pushup": "index.js"
7
7
  },
8
8
  "dependencies": {
9
- "@code-pushup/models": "0.44.4",
10
- "@code-pushup/core": "0.44.4",
11
- "@code-pushup/utils": "0.44.4",
9
+ "@code-pushup/models": "0.45.1",
10
+ "@code-pushup/core": "0.45.1",
11
+ "@code-pushup/utils": "0.45.1",
12
12
  "yargs": "^17.7.2",
13
13
  "chalk": "^5.3.0",
14
14
  "simple-git": "^3.20.0"